package webshop.web;

import java.util.List;
import java.util.Enumeration;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import webshop.data.Person;
import webshop.data.ShoppingBasket;
import webshop.data.Product;
import webshop.data.Orderline;

/**
 * A small utility class which helps us with common tasks related to the
 * person object. It is abit out of its scope, but we cant be all that
 * abstract all the bloody time. 
 *
 * @author simon
 */
public class PersonUtil {

    // Variables. 
    private EntityManager em;
    private HttpServletRequest request;

    // Constructors.
    /**
     * This class must be used with an Entity Manager Factory Object.
     * @param em Entity Manager Object. 
     */
    public PersonUtil(EntityManager em) {
        setEm(em);
    }

    /**
     * This class must be used with an Entity Manager Factory Object.
     * @param em Entity Manager Object.
     * @param request HTTP request object related to sessions and such. 
     */
    public PersonUtil(EntityManager em, HttpServletRequest request) {
        setEm(em);
        setRequest(request);
    }

    /**
     * Check if a there is a active session related to a person.
     * @return Person object or null.
     */
    public Person isActive() {
        HttpSession session = request.getSession();
        Person person = null;
        String name = null;

        for (Enumeration e = session.getAttributeNames(); e.hasMoreElements();) {
            if ((name = (String) e.nextElement()) != null) {
                if ((person = (Person) session.getAttribute(name)) != null) {
                    return person;
                }
            }
        }
        return null;
    }

    /**
     * Check if a person has a shopping basket
     * @return Person object or null.
     */
    public ShoppingBasket getShoppingBasket(Person person) {
        Query q = em.createNamedQuery("ShoppingBasket.selectAll");
        List<ShoppingBasket> baskets = q.getResultList();
        for (ShoppingBasket basket : baskets) {
            if (person.getPersonId() == basket.getPerson().getPersonId()
                && person.getShoppingBasketId() == basket.getShoppingBasketId()) {
                return basket;
            }
        }

        // Create new basket if it doesnt exits
        return createShoppingBasket(person);
    }

    /**
     * Change the shopping basket on a person.
     * @param shoppingBasket
     * @param person
     */
    public void setShoppingBasket(ShoppingBasket shoppingBasket, Person person){
        Person p = em.find(Person.class, person.getPersonId());
        p.setShoppingBasket(shoppingBasket);
        em.persist(p);
    }

    /**
     * Creates a new shopping basket for a person. Adds it as active.
     * @param person
     * @return
     */
    public ShoppingBasket createShoppingBasket(Person person){
        ShoppingBasket newBasket = new ShoppingBasket(person);
        em.persist(newBasket);
        Person p = em.find(Person.class, person.getPersonId());
        setShoppingBasket(newBasket, p);
        return person.getShoppingBasket();
    }
    
    /**
     * Add a product to basket.
     * @param product
     * @param shoppingBasket
     * @param quantity
     */
    public void addToBasket(Product product, ShoppingBasket shoppingBasket, int quantity) {
        Orderline order = findOrder(shoppingBasket, product);
        if (order != null) {
            quantity += order.getQuantity();
            order.setQuantity(quantity);
            em.persist(order);
        } else {
            order = new Orderline(product, shoppingBasket, quantity);
            em.persist(order);
            shoppingBasket.addProduct(order);
            product.addOrder(order);
        }
    }


    /**
     *
     * @param shoppingBasket
     * @param product
     * @return Orderline
     */
    public Orderline findOrder(ShoppingBasket shoppingBasket, Product product) {
        List<Orderline> orders = shoppingBasket.getProductList();
        for (Orderline order : orders) {
            if (order.getProductId() == product.getProductId()) {
                return order;
            }
        }
        return null;
    }

    /**
     * Find a matching person in the db.
     * @param name
     * @return A person Object or null.
     */
    public Person findPerson(String name) {
        Query q = em.createNamedQuery("Person.selectAll");
        List<Person> persons = q.getResultList();
        for (Person person : persons) {
            if ((person.getName().toLowerCase()).equals(name.toLowerCase())) {
                return person;
            }
        }
        return null;
    }

    /**
     * Find a product by matching name.
     * @param name
     * @return product.
     */
    public Product findProduct(String name) {
        Query q = em.createNamedQuery("Product.selectAll");
        List<Product> products = q.getResultList();
        for (Product p : products) {
            if (p.getName().toLowerCase().equals(name.toLowerCase())) {
                return p;
            }
        }
        return null;
    }

    // Getters and Setters.
    public EntityManager getEm() {
        return em;
    }

    public void setEm(EntityManager em) {
        this.em = em;
    }

    public HttpServletRequest getRequest() {
        return request;
    }

    public void setRequest(HttpServletRequest request) {
        this.request = request;
    }
}
